package com.htu.courseService.common.util;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.htu.courseService.common.config.MinioConfig;
import io.minio.*;
import io.minio.errors.*;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;

import javax.management.openmbean.InvalidKeyException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;

@Component
@RequiredArgsConstructor
public class MinioUtil {
    private final MinioClient minioClient;
    private final MinioConfig minioConfig;
    public String upload(MultipartFile file, String bucketName){
        String fileOriginalFileName = getFileOriginalFileName(Objects.requireNonNull(file.getOriginalFilename()));
        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileOriginalFileName)
                            .stream(file.getInputStream(), file.getInputStream().available(), -1)
                            .contentType(file.getContentType())
                            .build()
            );
        } catch (MinioException | IOException | NoSuchAlgorithmException | InvalidKeyException |
                 java.security.InvalidKeyException e) {
            e.printStackTrace();
        }
        return fileOriginalFileName;
    }
    public String upload(MultipartFile file){
       return upload(file,minioConfig.getBucketName());
    }
    private GetObjectResponse download(String filename,String bucketName){
        try {
           return  minioClient.getObject(GetObjectArgs.builder()
                    .bucket(bucketName)
                    .object(filename)
                    .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException |
                 java.security.InvalidKeyException | InvalidResponseException | IOException | NoSuchAlgorithmException |
                 ServerException | XmlParserException e) {
            throw new RuntimeException(e);
        }
    }

    public void download(String filename, HttpServletResponse res){
        try (GetObjectResponse response = download(filename, minioConfig.getBucketName())){
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
                while ((len=response.read(buf))!=-1){
                    os.write(buf,0,len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                // 设置强制下载不打开
                // res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + filename);
                try (ServletOutputStream stream = res.getOutputStream()){
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void preview(String fileUrl, HttpServletResponse res){
        try (GetObjectResponse response = download(fileUrl, minioConfig.getBucketName())){
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
                while ((len=response.read(buf))!=-1){
                    os.write(buf,0,len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                //res.setContentType("application/octet-stream");
                //res.setContentType("image/png");
                res.addHeader("Content-Disposition", "inline;fileName=" + fileUrl);
                //res.addHeader("Content-Type","application/octet-stream");
                try (ServletOutputStream stream = res.getOutputStream()){
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getFileOriginalFileName(String fileName){
        String res = "";
        String[] split = fileName.split("\\.");
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String s = String.valueOf(snowflake.nextId());
        if (split.length == 2){
            res = split[0] + "-" + s + "." +split[1];
        }else {
            res = split[0] + '-' +s;
        }
        return res;
    }

    public void delete(String fileUrl){
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(fileUrl).build());
        } catch (MinioException | IOException | NoSuchAlgorithmException | InvalidKeyException |
                 java.security.InvalidKeyException e) {
            e.printStackTrace();
        }
    }
}
